import { requestDefaultConfig, instanceDefaultConfig } from '../config.js';

import mergeConfig from '../utils/mergeConfig.js';

import defaultRequest from './request.js';

import InterceptorManager from './InterceptorManager.js';

class Http {
	// 默认的配置
	defaults = {
		...instanceDefaultConfig,
	};

	constructor(config) {
		this.defaults = config || {};
		// 创建 request 和 responese 的拦截器的钩子函数
		this.interceptors = {
			request: new InterceptorManager(),
			responese: new InterceptorManager(),
		};
	}

	/**
	 * 核心的请求方法
	 * @param {Object} config
	 */
	request(config) {

		// 处理入参
		// 允许两种请求方式
		// 1. http({}).then()
		// 2. http(url , {}).then()
		if (typeof config === 'string') {
			// 说明这是第二种
			config = arguments[1] || {};
			// 第一个参数就是请求的地址
			config.url = arguments[0];
		} else {
			config = config || {};
		}

		// 第二步 处理请求的配置数据
		config = mergeConfig(this.defaults, config);

		// 第三步 处理请求的方式
		if (config.method) {
			// 全部转换成大写
			config.method = config.method.toLocaleUpperCase();
		} else {
			config.method = 'GET';
		}

		// 处理定义的请求和返回拦截器
		// 对于拦截器的处理方式 是通过队列的方式进行处理的
		// 定义一个默认的队列数组
		let chain = [defaultRequest, undefined];
		const promise = Promise.resolve(config);
		// 如果请求之前定义了拦截器 那么就将定义的拦截器放到队列的前面
		this.interceptors.request.forEach(interceptor => {
			chain.unshift(interceptor.fulfilled, interceptor.rejected);
		});

		// 如果定义了responese拦截器 那么就将定义的拦截器放到队列的后面
		this.interceptors.responese.forEach(interceptor => {
			chain.push(interceptor.fulfilled, interceptor.rejected);
		});

		// 按照chain数组中函数的顺序一步一步处理
		while (chain.length) {
			promise = promise.then(chain.shift(), chain.shift());
		}

		return promise;
	}

	/**
	 * 获取当前请求的uri
	 * @param {Object} config
	 */
	getUri(config) {}

	/**
	 * 获取当前请求的uri
	 * @param {Object} config
	 */
	get(url, config) {}

	/**
	 * 获取当前请求的uri
	 * @param {Object} config
	 */
	post(url, data, config) {}
}

export default Http;
